package org.openspaces.example.helloworld.processor;


import java.awt.Point;

import org.openspaces.core.GigaSpace;
import org.openspaces.core.GigaSpaceConfigurer;
import org.openspaces.core.space.UrlSpaceConfigurer;
import org.openspaces.events.EventDriven;
import org.openspaces.events.EventTemplate;
import org.openspaces.events.adapter.SpaceDataEvent;
import org.openspaces.events.notify.Notify;
import org.openspaces.example.helloworld.common.Car;
import org.openspaces.example.helloworld.common.Direction;
import org.openspaces.example.helloworld.common.Roxel;
import org.openspaces.example.helloworld.common.StructureTuple;

import com.j_spaces.core.IJSpace;

@EventDriven @Notify
public class CarListener {

    @EventTemplate
    Roxel occupiedRoxel() {
        Roxel template = new Roxel();
        template.setId(null);
        template.setOccupied(true);
        return template;
    }
    
    @SpaceDataEvent
    public Roxel eventListener(Roxel roxel) {
    
    		if(roxel.isOccupied()==false){
    			
    			System.out.println("template error!");
    		}
    	  // connect to the space using its URL
    	  IJSpace space = new UrlSpaceConfigurer("jini://*/*/processorSpace").space();
    	  // use gigaspace wrapper to for simpler API
    	   GigaSpace gigaSpace = new GigaSpaceConfigurer(space).gigaSpace();
    	   
    	gigaSpace.take(roxel);
    	   
	        
    	 System.out.println("ausgangsroxel: " + roxel); 
    	   
	    Roxel tmp = gigaSpace.take(roxel);
    	System.out.println("ausm space genommen	: " + tmp);
	    

    	
    	int xTile = roxel.getTileCoords().x;
    	int yTile = roxel.getTileCoords().y;
    	int xRoxel = roxel.getX();
    	int yRoxel = roxel.getY();
    	Boolean north = roxel.getNorth();
    	Boolean east = roxel.getEast();
    	Boolean south = roxel.getSouth();
    	Boolean west = roxel.getWest();
    	StructureTuple struc = new StructureTuple();
    	struc.setProcessed(true);
    	struc = gigaSpace.read(struc);
    	
    	
        Roxel template = new Roxel();
        switch(roxel.getCar().getDir()){
        case NORTH :    
        	break; 
        case EAST :    
        	if (east){
    			template.setEast(true);
    			xRoxel++;
    			System.out.println("carlistener: moving east");
    			if (xRoxel >= struc.getBlockLen()){
    				xRoxel = 0;
    				xTile++;
    				if (xTile >= struc.getBlocksX()){
    					xTile = 0;
    				}
    			}
    			break; 
    		}
        case SOUTH : 
        	if (south){
    			yRoxel++;
    			System.out.println("carlistener: moving south");
    			if (yRoxel >= struc.getBlockLen()){
    				yRoxel = 0;
    				yTile++;
    				if (yTile >= struc.getBlocksY()){
    					yTile = 0;
    				}
    			}
    			break;
    		} 
        case WEST :    
        	break; 
        default:
        	if (east){
    			template.setEast(true);
    			xRoxel++;
    			System.out.println("carlistener: moving east");
    			if (xRoxel >= struc.getBlockLen()){
    				xRoxel = 0;
    				xTile++;
    				if (xTile >= struc.getBlocksX()){
    					xTile = 0;
    				}
    			}
    		}else if (south){
    			yRoxel++;
    			System.out.println("carlistener: moving south");
    			if (yRoxel >= struc.getBlockLen()){
    				yRoxel = 0;
    				yTile++;
    				if (yTile >= struc.getBlocksY()){
    					yTile = 0;
    				}
    			}
    		}
        }
		
		
        template.setId(null);
        template.setOccupied(false);
        template.setX(xRoxel);
        template.setY(yRoxel);
        template.setTileCoords(new Point(xTile, yTile));

        // wait 1000 ms:
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ie) { /*do nothing*/ }
        
		try{
//			int i = gigaSpace.count(template);
//			System.out.println("cnt: " + i);
			Roxel next = gigaSpace.take(template,100);
			System.out.println("carlistener: next roxel genommen");
			boolean ok = false;
			switch(roxel.getCar().getDir()){
	        case NORTH :    
	        	break; 
	        case EAST :    
	        	if (next.getEast()){
	        		ok = true;
	    			break; 
	    		}
	        case SOUTH : 
	        	if (next.getSouth()){
	        		ok = true;
	    			break;
	    		} 
	        case WEST :    
	        	break; 
	        default:
	        }
			if(next.isOccupied()) ok = false;
			if(!ok){
				gigaSpace.write(next);
				throw new NullPointerException();
			}else{
				next.setOccupied(true);
				next.setCar(roxel.getCar());
				gigaSpace.write(next);
			}
			
		}catch(NullPointerException e){
			System.out.println("no next");
			return roxel;
		}
		roxel.setOccupied(false);
		roxel.setCar(null);
		
		if(roxel.isXroads()){
			roxel.setNorth(false);
			roxel.setEast(false);
			roxel.setSouth(false);
			roxel.setWest(false);
		}
		
    	System.out.println("moved car");
    	return roxel;
    }
}

